package com.suray.wcs.service.config.resolver;

import com.alibaba.fastjson.JSON;
import com.suray.commin.annotation.RvgLog;
import com.suray.commin.core.utils.SpringContextHolder;
import com.suray.wcs.res.enums.RgvStatus;
import com.suray.wcs.res.msgparse.ByteBeanUtil;
import com.suray.wcs.res.msgparse.HeartBaseResult;
import com.suray.wcs.service.pojo.Rgv;
import com.suray.wcs.service.rescontact.ToRes;
import com.suray.wcs.service.system.entity.InterfaceLogRvg;
import com.suray.wcs.service.system.entity.RgvHeartLogDB;
import com.suray.wcs.service.system.service.impl.InterfaceLogRgvServiceImpl;
import com.suray.wcs.service.system.service.impl.RgvHeartLogServiceImpl;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

public class LogInterceptorRvg implements MethodInterceptor {
    InterfaceLogRgvServiceImpl interfaceLogRgvService = SpringContextHolder.getBean(InterfaceLogRgvServiceImpl.class);
    RgvHeartLogServiceImpl rgvHeartLogService = SpringContextHolder.getBean(RgvHeartLogServiceImpl.class);

    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {

        ToRes toRes = (ToRes) proxy;
        Field rgv = ToRes.class.getDeclaredField("rgv");
        rgv.setAccessible(true);
        Rgv r = (Rgv) rgv.get(toRes);
        // 注解对象
        RvgLog rvgLog = method.getAnnotation(RvgLog.class);
        // 返回结果初始化
        Object ret;
        // 是否拦截的方法是否记录日志到日志表
        if (rvgLog != null) {
            boolean useMethod = rvgLog.useMethod();
            if (!useMethod) {
                RgvHeartLogDB rgvHeartLogdb = new RgvHeartLogDB();
                rgvHeartLogdb.setDeviceName(r.getRgvName());
                long startTime = System.currentTimeMillis();
                long endTime;
                try {
                    ret = methodProxy.invokeSuper(proxy, args);
                } catch (Exception e) { // 捕获到方法异常记录到ex中，再抛出异常防止对正常业务的影响
                    endTime = System.currentTimeMillis();
                    rgvHeartLogdb.setSendTime(new Date(startTime));
                    rgvHeartLogdb.setReceTime(new Date(endTime));
                    rgvHeartLogdb.setRgvStatus(RgvStatus.OFF_LINE.getRgvStatus());
                    rgvHeartLogdb.setUseTime(endTime - startTime);
                    // 异常信息保存到日志表
                    rgvHeartLogService.setInterfaceLog(rgvHeartLogdb);
                    throw e;
                }
                endTime = System.currentTimeMillis();
                rgvHeartLogdb.setSendTime(new Date(startTime));
                rgvHeartLogdb.setReceTime(new Date(endTime));
                rgvHeartLogdb.setUseTime(endTime - startTime);

                // 返回对象为byte[]时的处理
                if (ret instanceof byte[]) {
                    HeartBaseResult d = (HeartBaseResult) ByteBeanUtil.parseByte((byte[]) ret);
                    rgvHeartLogdb.setTaskNo(d.getTaskNo());
                    rgvHeartLogdb.setTaskType(d.getTaskType());
                    rgvHeartLogdb.setTaskResult(d.getTaskResult());
                    rgvHeartLogdb.setRgvLocation("(" + d.getX() + "," + d.getY() + "," + d.getZ() + ")");
                    rgvHeartLogdb.setPalletStatus(d.getPalletStatus());
                    rgvHeartLogdb.setRgvCurrentSegment(d.getCurentSegment());
                    rgvHeartLogdb.setSegmentEndLocation("(" + d.getX() + "," + d.getY() + "," + d.getZ() + ")");
                    rgvHeartLogdb.setCurBarcode(String.valueOf(d.getCurBarcode()));
                    rgvHeartLogdb.setRgvStatus(d.getRgvStatus() != null ? d.getRgvStatus() : 255);
                    rgvHeartLogdb.setReserveStatus(d.getReserveStatus());
                    rgvHeartLogdb.setDriveDirection(d.getDriveDirection());
                    rgvHeartLogdb.setElectric(d.getBattery());
                    rgvHeartLogdb.setCmdNo(d.getCmdNo());
                    rgvHeartLogdb.setCmdResult(d.getCmdResult());
                    rgvHeartLogdb.setCmdExecuteResult(d.getCmdExecuteResult());
                    rgvHeartLogdb.setCmdExecuteResultParam(d.getCmdExecuteResultParam());
                    // 日志记录保存到表
                    rgvHeartLogService.setInterfaceLog(rgvHeartLogdb);
                }
            } else {
                InterfaceLogRvg interfaceLogRvg = new InterfaceLogRvg();
                interfaceLogRvg.setMessage(rvgLog.value());
                interfaceLogRvg.setDeviceName(r.getRgvName());
                // 方法传入参数为byte[]的处理
                if (args != null && args.length == 1 && args[0] instanceof byte[]) {
                    interfaceLogRvg.setRgvParamsIn(Arrays.toString((byte[]) args[0]));
                } else { // 方法传入参数为非byte[]的处理

                    interfaceLogRvg.setTackId(args.length != 0 ? (Integer) args[0] : null);
                    List<Object> argList = Arrays.asList(args);
                    List<Object> newArgs = new ArrayList<>(argList);
                    if (newArgs.size() > 0) {
                        newArgs.remove(0);
                    }
                    interfaceLogRvg.setRgvParamsIn(newArgs.size() == 0 ? "无" : newArgs.toString());
                }
                long startTime = System.currentTimeMillis();
                long endTime;
                try {
                    ret = methodProxy.invokeSuper(proxy, args);
                } catch (Exception e) { // 捕获到方法异常记录到ex中，再抛出异常防止对正常业务的影响
                    endTime = System.currentTimeMillis();
                    interfaceLogRvg.setOperateTime(new Date(startTime));
                    interfaceLogRvg.setUseTime(endTime - startTime);
                    interfaceLogRvg.setState(1);
                    interfaceLogRvg.setRgvParamsIn(JSON.toJSONString(e == null ? "" : e));
                    // 异常信息保存到日志表
                    interfaceLogRgvService.setInterfaceLogRgv(interfaceLogRvg);
                    throw e;
                }

                endTime = System.currentTimeMillis();
                interfaceLogRvg.setOperateTime(new Date(startTime));
                interfaceLogRvg.setUseTime(endTime - startTime);
                interfaceLogRvg.setState(0);

                // 返回对象为byte[]时的处理
                if (ret instanceof byte[]) {
                    interfaceLogRvg.setBacktrack(Arrays.toString((byte[]) ret));
                } else { // 返回对象b为非byte[]时的处理
                    interfaceLogRvg.setBacktrack(JSON.toJSONString(ret == null ? "无" : ret));
                }
                // 日志记录保存到表
                interfaceLogRgvService.setInterfaceLogRgv(interfaceLogRvg);
            }
        } else {
            try {
                ret = methodProxy.invokeSuper(proxy, args);
            } catch (Exception e) {
                throw e;
            }
        }
        return ret;
    }
}
